package com.rtsapp.server.benchmark.exp;

import com.rtsapp.server.utils.StringUtils;
import com.rtsapp.server.logger.Logger;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 *  表示工具, 根据表达式计算值
 *  表达式规则为:
 *
 *
 */
public class ExpUtils {


    private static Logger log =com.rtsapp.server.logger.LoggerFactory.getLogger(ExpUtils.class);

    private static final Pattern ExpPattern = Pattern.compile( "(([^\\{\\}]+)|(\\{.*?\\}))" );

    private static ExpressionParser parser = new SpelExpressionParser( );


    /**
     * 从对象中获取表达式的值
     * @param obj 对象
     * @param exp 表达式
     * @return 获取的值
     */
    public static Object getValue( Object obj, String exp ){
        return  parser.parseExpression( exp ).getValue( obj );
    }

    /**
     * 从测试上下文中获取表达式的值
     * @param ctx 上下文
     * @param exp 表达式
     * @return 获取的值
     */
    public static Object getValue( Map ctx, String exp ){

        if( StringUtils.isEmpty( exp ) ){
            return exp;
        }

        StandardEvaluationContext context = new StandardEvaluationContext( );
        context.setVariables(ctx);

        return parser.parseExpression( exp ).getValue( context );
    }

    public static Object getValue( String exp ){
        return parser.parseExpression( exp ).getValue( );
    }


    /**
     * 设置对象的属性的值
     * @param obj 对象
     * @param propExp 属性的表达式
     * @param value 要设置的值
     */
    public static void setValue( Object obj, String propExp, Object value ){
        parser.parseExpression( propExp ).setValue(obj, value);
    }


    /**
     * 转换表达式, 主要用于xml配置时,特殊的配置方式
     * @param exp 原始的表达式
     * @param isContext 是否在上下文中 ， 或者在对象中
     * @return 转换后的表达式
     */
    public static String tranforExpInXmlAttrName( String exp, boolean isContext ){

        exp = exp.replaceAll( "(\\.)(\\d+?)","[$2]" );
        exp = exp.replace( "__", "()" );

        if( isContext ){
            return "#" + exp;
        }
        return exp;
    }


    public static void main(String[] args ){

        String str = "shopList.1.propId.2.count.size__.length__.k__.1.bc";

        System.out.println( tranforExpInXmlAttrName( str, false ) );
        System.out.println( tranforExpInXmlAttrName( str, true ) );

    }

}
